<template>
    <div>
        <el-upload class="super_upload" ref="upload" :headers="headers" :accept="accept" :action="action"
            :show-file-list="false" :file-list="fileList" :before-upload="beforeUpload" :on-progress="handleProgress"
            :on-success="handleSuccess" :on-error="handleError" :on-change="handleChange" :limit="limit" :multiple="multiple"
            :on-exceed="onExceed" :disabled="disabled" :drag="drag">
            <slot v-if="type == 'file'" name="trigger">
                <el-button icon="el-icon-upload" slot="trigger" v-if="!disabled">
                    {{ $tt('label_upload_file') }}
                </el-button>
            </slot>
            <div v-if="type == 'image'" class="upload_image_div">
                <div class="upload_image_content" @click.stop="" v-for="(item, index) in fileList" :key="index">
                    <div class="upload_image_box" :style="{ width: imageBoxSize + 'px',height: imageBoxSize + 'px' }"
                        v-if="item.status == 'ready' || item.status == 'uploading'">
                        <el-progress type="circle" :percentage="_numberProgress(item)" :width="imageBoxSize"></el-progress>
                    </div>
                    <div class="upload_image_box" :style="{ width: imageBoxSize + 'px', height: imageBoxSize + 'px' }" v-else>
                        <i class="el-icon-error delete-icon" v-if="!disabled"  :style="{'font-size':imageBoxSize/4 + 'px'}"
                        @click.stop="handleDelete(item, index)"></i>
                        <el-image style="width: 100%; height: 100%" :src="fixLink(item)" fit="contain"
                            :preview-src-list="urlList">
                            <div slot="placeholder" class="el-image__error">
                                <i class="el-icon-loading"></i>{{ $tt('tip_loading') }}<span class="dot">...</span>
                            </div>
                        </el-image>
                    </div>
                </div>
                <div v-if="fileList.length < limit && !disabled" :style="{ width: imageBoxSize + 'px', height: imageBoxSize + 'px' }"
                    class="upload_image_box upload_image_plus_box" slot="trigger">
                    <i class="el-icon-plus upload_image_plus"></i>
                </div>
            </div>
            <div slot="tip" class="el-upload-tip" v-if="!!limitTip">
                <template v-if="typeof (limitTip) == 'string'">
                    {{ limitTip }}
                </template>
                <template v-else>
                    <div>
                        {{ $tt('label_file_maxSize_m', { maxSize }) }}
                    </div>
                    <div>
                        {{ $tt('label_format_limit') }} : {{ accept }}
                    </div>
                    <!-- 文件最大{{ maxSize }}M，格式： {{ accept }} -->
                </template>
            </div>
        </el-upload>
        <div v-if="type == 'file' && fileList.length" @click.stop="" class="form-file-list">
            <div v-for="(item, i) in fileList" :key="item.filePath" class="form-file-item">
                <div class="item">
                    <div v-if="checkImg(item)" class="img-box">
                        <el-image class="img-item" :src="fixLink(item)" :preview-src-list="urlList" />
                        <a class="img-url upload-fileName   upload-result-color" :href="fixLink(item)" target="_blank">{{
                            item.fileName || item.name }}</a>
                    </div>
                    <div v-else class="media-box  upload-result-color">
                        <a class="upload-fileName" v-if="!item.status || item.status == 'success'" :href="fixLink(item)"
                            :download="item.fileName || item.name" target="_blank">{{
                                item.fileName || item.name
                            }}</a>
                        <span class="upload-fileName" v-else>{{ item.fileName || item.name }}</span>
                    </div>
                    <div class="color-primary el-icon--left  icon_percentage upload-result-color"
                        v-show="item.status == 'uploading'">
                        <i class="el-icon-loading color-primary  "></i>
                        <span> {{ _numberProgress(item.percentage) }} </span>
                    </div>
                </div>
                <div class="el-center-icon">
                    <i v-if="!disabled" class="el-icon-delete el-delete-icon" @click.stop="handleDelete(item, i)" />
                </div>

            </div>
        </div>
    </div>
</template>

<script>

// 检测图片的正则
const imgReg = /\.png|jpg|jpeg|gif$/i

export default {

    data() {
        return {
            fileList: this.value,
        };
    },
    props: {

        value: {
            type: Array,
            default: () => []
        },
        accept: {
            type: String,
            default: '',//'image/png,image/jpeg'
        },
        action: {
            type: String,
            default() {
                return this.$ex_default_upload_url;
            }
        },
        downloadUrl: {
            type: String,
            default() {
                return this.$ex_default_download_url;
            }
        },
        limit: {
            type: Number,
            default: null,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        type: {
            type: String,
            default() {
                return "image";
            }
        },
        headers: {
            type: Object,
            default() {
                return {};
            }
        },
        drag: {
            type: Boolean,
            default: false
        },
        multiple: {
            type: Boolean,
            default: false
        },
        // 最大上传文件大小 单位: m
        maxSize: {
            type: Number,
            default: 10
        },
        imageBoxSize: {
            type: Number,
            default: 150
        },
        limitTip: {
            type: [String, Boolean],
            default: false
        }
    },

    watch: {
        value(val, oldValue) {
            this.fileList = JSON.parse(JSON.stringify(val))
        }
    },
    computed: {
        urlList: function () {
            return this.value.map(it => this.fixLink(it))
        },
    },
    methods: {
        _isURL(str_url) {
            var re = new RegExp(/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/);
            if (re.test(str_url)) {
                return (true);
            } else {
                return (false);
            }
        },
        _numberProgress(item) {
            return (item && item.percentage && Number(item.percentage.toFixed(0))) || 0
        },
        fixLink(item) {

            if (item.filePath) {
                if (this._isURL(item.filePath)) {
                    return item.filePath
                } else {
                    return this.downloadUrl + item.filePath
                }
            }
            return ''
        },
        fileExt(filename) {
            return /[.]/.exec(filename) ? /[^.]+$/.exec(filename)[0] : null
        },
        beforeUpload(file) {

            if (file.size > this.maxSize * 1024 * 1024) {
                this.$message({
                    message: this.$tt(`tip_file_no_more_max_size`, { maxSize: this.maxSize }),
                    type: 'error'
                })
                return false;
            }

            // if (this.accept && (this.accept.indexOf(file.type) == -1 && this.fileExt())) {
            if (this.accept) {
                const acceptList = this.accept.split(',')
                const ext = '.' + this.fileExt(file.name)
                if (!acceptList.includes(file.type) && !acceptList.includes(ext)) {
                    this.$message({
                        message: this.$tt('tip_file_type_not_allowed_only_type', { type: this.accept }),
                        type: 'error'
                    })
                    return false;
                }
            }

        },
        onExceed(files, fileList) {
            this.$message.error(this.$tt(`tip_file_limit_select`, { limit: this.limit }),)
        },
        dowithFiles(file, fileList) {
            const list = fileList.map(it => {
                if (it.response) {
                    const { response, raw, ...other } = it
                    if (response.code == 0) {
                        const item = {
                            ...response.data,
                            ...other,
                        }
                        return item
                    } else {
                        this.$message.error(response.message || this.$tt('上传失败'));
                        return null
                    }
                } else {
                    return it
                }
            }).filter(it => it)
            return list
        },
        checkImg(item) {
            return item && item.filePath && item.filePath.match(imgReg)
        },
        handleDelete(item, i) {
            const list = _.cloneDeep(this.value)
            list.splice(i, 1)
            this.$emit('input', list);
        },
        checkIsUpload(fileList) {
            const isUpload = fileList.some(item => item.status == 'ready' || item.status == 'uploading')
            this.$emit('isUploadChange', isUpload);
            this.$emit('update:isUpload', isUpload);
        },
        handleChange(file, fileList) {
            // console.log("Change", JSON.stringify(file))
            this.fileList = this.dowithFiles(file, fileList)
            this.checkIsUpload(fileList)
            // this.$emit('input', this.dowithFiles(file, fileList));

        },
        handleSuccess(res, file, fileList) {
            // console.log("Success", JSON.stringify(file))
            this.$emit('input', this.dowithFiles(file, fileList));
        },

        handleError(err, file, fileList) {
            // console.log("Error", JSON.stringify(file))
            this.$emit('input', this.dowithFiles(file, fileList));
        },

        handleProgress(event, file, fileList) {
            fileList.forEach(it => {
                const item = _.find(this.fileList, file => file.uid == it.uid)
                if (item) {
                    this.$set(item, 'percentage', it.percentage)
                    this.$set(item, 'status', it.status)
                }
            })

            // console.log("Progress", JSON.stringify(file))
            // this.fileList = fileList
        },

    }
}

</script>
<style scoped>
.super_upload .el-upload-tip {
    padding-top: 6px;
    color: #999;
    font-size: 12px;
    line-height: 22px;
}

.upload_image_div {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    cursor: default;
}

.upload_image_content {
    padding-bottom: 5px;
    padding-top: 5px;
    padding-right: 10px;
}

.upload_image_box {
    position: relative;
    width: 150px;
    height: 150px;
    background-color: #fbfdff;
    border: 2px dashed #c0ccda;
    border-radius: 6px;
    cursor: pointer;
}

.upload_image_plus_box {
    margin-bottom: 5px;
    margin-top: 5px;
    cursor: pointer;
}

.upload_image_box>.el-image {
    border-radius: 6px;
}

.upload_image_box>.upload_image_plus {
    font-size: 28px;
    color: #8c939d;
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: col;
    justify-content: center;
    align-items: center;
}



.delete-icon {
    position: absolute;
    right: 3px;
    top: 3px;
    color: rgba(0, 0, 0, 0.7);
    /* font-size: 32px; */
    z-index: 50;
}

.delete-icon:hover {
    color: rgba(0, 0, 0, 1);
}

.upload-fileName {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}




.form-file-list .form-file-item {

    line-height: 30px;
    transition: all 0.15s;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}


.form-file-list .form-file-item .item {
    display: flex;
    flex-direction: row;
    align-items: center;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}


.form-file-list .form-file-item:not(:last-child) {
    padding-bottom: 4px;
}

.form-file-list .form-file-item .img-box {
    width: 100%;
    display: flex;
}

.form-file-list .form-file-item .img-box .img-item {
    width: 30px;
    height: 30px;
    margin-right: 4px;
}

.form-file-list .form-file-item .img-box .img-url {
    flex: 1;
    font-size: 12px;
}

.form-file-list .form-file-item .media-box {
    flex: 1;
    line-height: 30px;
    padding: 0 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.form-file-list .form-file-item .el-center-icon {
    display: flex;
    align-items: center;
    justify-content: center;
}

.form-file-list .form-file-item .el-delete-icon {

    line-height: 30px;
    color: #606266;
    margin: 0 5px;
    visibility: hidden;
    opacity: 0;
    transition: all 0.15s;
    cursor: pointer;
}

.form-file-list .form-file-item:hover {
    background-color: #f5f7fa;
}

.form-file-list .form-file-item:hover .el-icon-delete {
    opacity: 1;
    visibility: visible;
}

.upload-result-color {
    color: #3A82D5;
    font-size: 12px;
}


.upload-result-color a {
    color: #3A82D5
}
</style>

